#include "func_iap.h"
#include "w25qxx.h"
#include "easyflash.h"
#include "net_protocol_update.h"
#define LOG_TAG "iap"
#ifdef EF_USING_IAP
#ifdef USE_HTTP_UPDATE
extern EfErrCode ef_iap_init(uint32_t app_start_addr);

/*进行累加校验*/
uint16_t check_bin(uint16_t pre_check, uint8_t *data, uint16_t len)
{
    static int test_count = 0;
    test_count += len;
    uint16_t check = pre_check;
    for (int i = 0; i < len; i++)
    {
        check += *(data + i);
    }

    return check;
}

void set_upgread_flag(uint8_t upgread_flag, uint32_t size, uint16_t check)			//写标志位
{
    uint8_t buf[8] = {0};
    buf[0] = upgread_flag;
    buf[1] = (uint8_t)(size >> 24);     //大小
    buf[2] = (uint8_t)(size >> 16);
    buf[3] = (uint8_t)(size >> 8);
    buf[4] = (uint8_t)(size);
    buf[5] = (uint8_t)(check >> 8);
    buf[6] = (uint8_t)check;
    buf[7] = 0;
    EN25QXX_Write(buf, UPGRADE_FLAG_ADDR, 8);
}

int update_check() {
    if(strcmp(ef_get_env("is_up"), "1") == 0) {
        printf(">>>> upgrade tasks already exist\n");
        return -1;
    }
    return 0;
}

void update_start(size_t size) {
    ef_set_env("is_up", "1");
    ef_iap_init(BK_APP_ADDR);
		printf("waiting for erase_bak_app...\n");
    ef_erase_bak_app(BK_APP_SIZE + UPGRADE_FLAG_SIZE + OLD_APP_SIZE);
}
void update_start_subset(size_t size) {
    ef_set_env("is_up", "1");
    ef_iap_init(SUBSET_APP_ADDR);
    ef_erase_bak_app(SUBSET_APP_SIZE);
}
EfErrCode update_write(uint8_t *data, size_t size, size_t *cur_size, size_t total_size) {
    return ef_write_data_to_bak(data, size, cur_size, total_size);
}

void update_end(size_t size, uint16_t check) {
    set_upgread_flag(NEED_UPGRADE_FLAG, size, check);
    ef_set_env("is_up", "0");
    ef_save_env();
		//delay_ms(1000);
    NVIC_SystemReset();

}


//int test_up(uint8_t argc, char **argv) {			//模拟升级，会升级失败 回滚
//	update_end(100000,6496);

//}
//CMD_EXPORT(test_up,test);
#include "net_protocol_mqtt.h"
int stop_recover_old_app_upload_result()			//获取boot的升级结果
{
    uint32_t isUpdata = NULL;
    uint8_t buf[8] = {0};
    EN25QXX_Read(buf, UPGRADE_FLAG_ADDR, 8);
    isUpdata = buf[0];
		char pub_topic[50];
    if (isUpdata == SUCCESSED_UPGRADE_FLAG)
    {

        log_i("upgread successed! stop rollback old app\n");
			#if defined(USE_USER_UPDATE)
        upload_update_result(0x00);
			#elif defined(USE_HTTP_UPDATE)
				//printf("使用MQTT上报升级成功\n");
//				split_topic_by_id(pub_topic,sizeof(pub_topic),PUB_TOPIC_PREFIX,UPDATE_UP_RESULT_TOPIC_SIFFIX,ef_get_env("device_id"));
//				reply_update_up_result_topic_handler(pub_topic,1);
				
			#endif
        buf[0] = 0;
        EN25QXX_Write(buf, UPGRADE_FLAG_ADDR, 8);
			return 1;
    }
    else if (isUpdata == ERR_UPGRADE_FLAG)
    {
        log_e("firmware check was fail\n");
			
			#if defined(USE_USER_UPDATE)
        upload_update_result(0x0A);
			#elif defined(USE_HTTP_UPDATE)
				//printf("使用MQTT上报升级失败\n");
//				split_topic_by_id(pub_topic,sizeof(pub_topic),PUB_TOPIC_PREFIX,UPDATE_UP_RESULT_TOPIC_SIFFIX,ef_get_env("device_id"));
//				reply_update_up_result_topic_handler(pub_topic,0);

			#endif
        buf[0] = 0;
        memset(buf, 0, 7);
        EN25QXX_Write(buf, UPGRADE_FLAG_ADDR, 8);
        return -1;
    }
    return 0;
}


int recover_old_app(uint8_t argc, char **argv) {			//回滚到老APP 

    uint8_t buf[8] = {0};
		//memset(buf,0,8);
		EN25QXX_Read(buf, UPGRADE_FLAG_ADDR, 8);
    buf[0] = SUCCESSED_UPGRADE_FLAG;
    EN25QXX_Write(buf, UPGRADE_FLAG_ADDR, 8);
		reboot();
}
//CMD_EXPORT(recover_old_app,test);



#if 0
/***********   升级例子   **************/
//0、定义全局变量
uint16_t g_check_value = 0;		//每次累加（全局）
uint16_t cur_write_size = 0;		//每次累加（全局）

//1、往flash写入升级包
if (!update_write(pack, updata_pack_length, (size_t *)&cur_write_size, (all_packet_num * one_packet_length/*升级包的总大小*/)))
{
    g_check_value = check_bin(g_check_value, pack, updata_pack_length);
    printf("write succesd pack len:%d , cur write size %d ,total size %d\n", updata_pack_length, cur_write_size, all_packet_num * one_packet_length);
}
else
{
    printf("write error request:%d \n", cur_packet_index);
    request_update_pack_send(cur_packet_index);
    return 1;
}

//2、下载结束，进入boot烧录升级
update_end(cur_write_size, g_check_value);

#endif

#endif

#endif


